<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>17.2.1-带有 v-if 指令的节点</title>
</head>
<body>
    <!-- 参考例子 1 -->
    <div>
        <section v-if="foo">
            <p>{{ a }}</p>
        </section>
        <div v-else>
            <p>{{ a }}</p>
        </div>
    </div>

    <!-- 参考例子 2 -->
    <div>
        <section v-if="foo">
            <p>{{ a }}</p>
        </section>
        <section v-else> <!-- 即使这里是 section -->
            <div> <!-- 这个 div 标签在 Diff 过程中被忽略 -->
                <p>{{ a }}</p>
            </div>
        </section>
</body>
    <script>
        /**
         * 
        */

        /**
         * 参考例子 1
         * 假设只有最外层的 div 标签会作为 Block 角色
         * - 无论变量 foo 的值是 true 还是 false，block 所收集的动态节点是不变的
         * - 意味着，在 Diff 阶段不会做任何更新
         * - 带有 v-if 指令的是 <section> 标签，而带有 v-else 指令的是 <div> 标签。
         * - 很明显，更新前后的标签不同，如果不做任何更新，将产生严重的 bug
         * */  
        // 当变量 foo 的值为true 时，block 收集到的动态节点是：
        const block = {
            tag: 'section',
            dynamicChildren: [
                { tag: 'p', children: ctx.a, patchFlags: 1 }
            ]
        }
        // 当变量 foo 的值为 false 时，block 收集到的动态节点是：
        const block2 = {
            tag: 'div',
            dynamicChildren: [
                { tag: 'p', children: ctx.a, patchFlags: 1 }
            ]
        }


        /**
         * 参考例子 2
         * 
         * 即使带有 v-if 指令的标签与带有 v-else 指令的标签都是 <section> 标签，
         *  但由于两个分支的虚拟 DOM 树的结构不同，仍然会导致更新失败。
         * 
         * 根本原因在于，dynamicChildren 数组中收集的动态节点是忽略虚拟 DOM 树层级的。
         *  换句话说，结构化指令会导致更新前后模板的结构发生变化，即模板结构不稳定
         * 
         * 如何让虚拟 DOM 树的结构变稳定
         * - 需要让带有 v-if/v-else-if/v-else 等结构化指令的节点也作为 Block 角色
         * 
         *  Block 树:
         *  - Block(Div)
         *    + Block(Section v-if)
         *    + Block(Section v-else)
         * 
         * 两个子 Block(section) 将作为父级 Block(div) 的动态节点
         *  被收集到父级Block(div) 的 dynamicChildren 数组中
         * - 当 v-if 条件为真时，父级 Block 的 dynamicChildren 数组中包含的是 Block(section v-if)
         * - 当 v-if 的条件为假时，父级 Block 的dynamicChildren 数组中包含的将是 Block(section v-else)
         * - Diff 过程中，渲染器能够根据 Block 的 key 值区分出更新前后的两个 Block 是不同的，
         *    并使用新的 Block 替换旧的 Block
         * 
        */

        const block3 = {
            tag: 'div',
            dynamicChildren: [
                /* Block(Section v-if) 或者 Block(Section v-else) */
                {
                    tag: 'section',
                    key: 0, /* key 值会根据不同的 Block 而发生变化 */
                    dynamicChildren: [
                        { tag: 'p', children: ctx.a, patchFlags: 1 }
                    ]
                },
                // {
                //     tag: 'section',
                //     key: 1,
                //     dynamicChildren: [
                //         { tag: 'div', children: ctx.a, patchFlags: 1 }
                //     ]
                // }
            ]
        }


        

    </script>
</html>